/**
 #        ┏┓   ┏┓+ +
 #   ┏┛┻━━━┛┻┓ + +
 #   ┃       ┃
 #   ┃   ━   ┃ ++ + + +
 #    ┃ ████━████  ┃+
 #   ┃       ┃ +
 #   ┃   ┻   ┃
 #   ┃       ┃ + +
 #   ┗━┓   ┏━┛
 #     ┃   ┃
 #     ┃   ┃ + + + +
 #     ┃   ┃    Codes are far away from bugs with the animal protecting
 #     ┃   ┃ +     神兽保佑,代码无bug
 #     ┃   ┃
 #     ┃   ┃  +
 #     ┃    ┗━━━┓ + +
 #     ┃        ┣┓
 #     ┃        ┏┛
 #     ┗┓┓┏━┳┓┏┛ + + + +
 #      ┃┫┫ ┃┫┫
 #      ┗┻┛ ┗┻┛+ + + +
 */
import React, {memo, useEffect, useRef, useState} from 'react';
import {useDispatch, useSelector} from "react-redux";

import "./plate.css";
import Header from "../../../components/main-header/Header";
import ExperimentName from "../../../components/experimentName/ExperimentName";
import Title from "../../../components/Title/Title";
import {MENU_STYLE, SAMPLE_TASK, WELL_LEFT, WELL_WIDTH, WELLS_COLUMN, WELLS_COUNTER, WELLS_COUNTER_CN, WELLS_ROW} from "./config";
import {deepClone, generateUUID, getAnalysisInfo} from "../../../common/utils";
import PlateTargets from "./components/PlateTargets";
import PlateSamples from "./components/PlateSamples";
import PlateGroup from "./components/PlateGroup";
import PlateTargetLibrary from "./components/PlateTargetLibrary";
import PlateStandard from "./components/PlateStandard";
import {saveAnalysisShowLineArr, saveEndogenousControlTarget, saveGroup, saveReferenceSample, saveTargetName} from "./store/actionCreators";
import {Dropdown, Menu} from "antd";
import {WELL_TYPE} from "../store/constants";
import {saveData} from "../store/actionCreators";
import {saveTargetSelectedArr} from "../analysis/components/quantification/store/actionCreators";
import {LOAD_PLATE} from "../../../common/loadType";
import {saveExportObj, saveExportObjCn} from "../export/store/actionCreators";
import {useDebounce} from "../../../common/myHooks";
import {saveRunTargetSelectedArr} from "../run/components/realtimeCurve/store/actionCreators";
import {saveExperimentSetting} from "../analysis/components/geneExpression/store/actionCreators";
import PlateSampleLibrary from "./components/PlateSampleLibrary";
import Login from "../../login/Login";

let globeWell = []; //  全局的well,用于粘贴复制时获取实时数据
let globeCopyWell = {};
export default memo(function Plate() {
  const dispatch = useDispatch();
  const {data, targetSelectedArr, channels, reduxGroup, exportObj, exportObjCn, referenceSample, endogenousControlTarget, experimentSetting, isCN, samples_, navigationIndex} = useSelector(state => ({
    data: state.dataReducer.data,
    channels: state.protocolReducer.scanChannel,
    reduxGroup: state.plateReducer.reduxGroup,
    exportObj: state.exportReducer.exportObj,
    exportObjCn: state.exportReducer.exportObjCn,
    endogenousControlTarget: state.plateReducer.endogenousControlTarget,
    referenceSample: state.plateReducer.referenceSample,
    experimentSetting: state.geneSettingReducer.experimentSetting,
    isCN: state.languageReducer.isCN,
    samples_: state.plateReducer.samples_,
    navigationIndex: state.navigationReducer.navigationIndex,
    targetSelectedArr: state.quantificationReducer.targetSelectedArr //  保存Target Setting中Opt被选中的target的name
  }));
  const wellsContainer = useRef();  //  Wells容器
  const [showSelectBox, setShowSelectBox] = useState(false);  // 是否开启框选功能
  const [showRightMenu, setShowRightMenu] = useState(false);  // 右键菜单
  const [showWellInfo, setShowWellInfo] = useState(false);  // wellInfo
  const [wellInfo, setWellInfo] = useState({});  // wellInfo显示内容
  const [mouseIn, setMouseIn] = useState(false);  //  鼠标是否进入plate
  const [mouseX, setMouseX] = useState(0);  //  鼠标横坐标
  const [mouseY, setMouseY] = useState(0);  //  鼠标纵坐标
  const [startX, setStartX] = useState(0);  //  鼠标按下起始位置横坐标
  const [startY, setStartY] = useState(0);  //  鼠标按下起始位置纵坐标
  const [selectBoxWidth, setSelectBoxWidth] = useState(0);  //  选择框宽度
  const [selectBoxHeight, setSelectBoxHeight] = useState(0);  //  选择框高度
  const [selectBoxLeft, setSelectBoxLeft] = useState(0);   //  选择框原点横坐标
  const [selectBoxTop, setSelectBoxTop] = useState(0);   //  选择框原点纵坐标
  const [rightMenuLeft, setRightMenuLeft] = useState(0);   //  右键菜单横坐标
  const [rightMenuTop, setRightMenuTop] = useState(0);   //  右键菜单纵坐标
  const [wellInfoTop, setWellInfoTop] = useState(0);   //  鼠标悬停纵坐标
  const [wellInfoLeft, setWellInfoLeft] = useState(0);   //  鼠标悬停横坐标
  const [leftMouseDown, setLeftMouseDown] = useState(false);  // 鼠标左键是否按下
  const [wells, setWells] = useState(data.wells);  //  96个孔板对象
  const [wellsId, setWellsId] = useState(-1);  //  选中well的sample ID
  const [target, setTarget] = useState(data.plateSetting.targets);  //  target条目
  const [sample, setSample] = useState(data.plateSetting.samples);  //  sample条目
  const [samples, setSamples] = useState(samples_);  //  sample条目
  const [standard, setStandard] = useState(data.plateSetting.standard);  //  standard条目
  const [group, setGroup] = useState(reduxGroup);  //  group条目
  const [selectedWells, setSelectedWells] = useState([]); //  选中的Wells
  const [targetLibrary, setTargetLibrary] = useState(getTargetLibraryLocalStorage());  //  target Library
  const [showTargetsLibrary, setShowTargetsLibrary] = useState(false);  // 显示target library
  const [targetLibraryStorage, setTargetLibraryStorage] = useState(getTargetLibraryLocalStorage()); // target library本地存储
  const [showSampleLibrary, setShowSampleLibrary] = useState(false);   //显示sample library
  const [targetNameArr, setTargetNameArr] = useState([]);  //  存放target name的数组
  const [wellsCounter, setWellsCounter] = useState(isCN ? WELLS_COUNTER_CN : WELLS_COUNTER); //  Wells Counter
  const [endogenousControl, setEndogenousControl] = useState("");  //  内参基因
  const [endogenousControlBox, setEndogenousControlBox] = useState(false);  //  多内参基因选择框
  let cloneWells = [];
  let cloneData = {};
  let cloneTarget = [];
  let cloneSample = [];
  let cloneGroup = [];
  let cloneSelectedWells = [];
  let cloneWellsCounter = [];
  let cloneEndogenousControlTarget = [];
  let cloneExperimentSetting = [];
  let data_plateSetting = {};
  useEffect(() => {
    cloneWells = deepClone(wells, cloneWells);
    cloneData = deepClone(data, cloneData);
    cloneTarget = deepClone(target, cloneTarget);
    //TODO:data.targets与data.plateSetting返回不一致,导致分析界面修改的值被修改，曲线消失
    data.targets.forEach(it => {
      const index = cloneTarget.findIndex(t => t.name === it.name);
      if (index === -1) {
        return;
      }
      cloneTarget[index].k = it.k;
      cloneTarget[index].b = it.b;
      cloneTarget[index].r2 = it.r2;
      cloneTarget[index].e = it.e;
      cloneTarget[index].threshold = it.threshold;
    });
    let lineData = getAnalysisInfo(data);
    cloneWells.forEach(well => well.targets.forEach(target => cloneTarget.forEach(item => { //  保证targets对象中的内容和well中targets对象的内容一致
      if (item.uuid === target.uuid) {
        target.color = item.color;
        target.channel = item.channel;
        target.quencher = item.quencher;
        target.comments = item.comments;
        target.k = item.k;
        target.b = item.b;
        target.r2 = item.r2;
        target.e = item.e;
        target.threshold = item.threshold;
      }
    })));
    cloneWells.forEach(well => sample.forEach(item => well.sampleName && well.sampleUuid === item.uuid && (well.sampleColor = item.color)));
    cloneWells.forEach(well => group.forEach(item => well.groupName && well.groupUuid === item.uuid && (well.groupColor = item.color)));
    data_plateSetting = {
      targets: target,
      samples: sample,
      standard: standard
    };
    dispatch(saveGroup(group));
    dispatch(saveAnalysisShowLineArr(lineData.analysisShowLineArr)); //  保存可以画线的数据(只有target和sample同时选择后才能画线)
    // dispatch(saveTargetSelectedArr([...new Set(lineData.targetSelectedArr)]));
    dispatch(saveRunTargetSelectedArr([...new Set(lineData.targetSelectedArr)]));
    dispatch(saveData({...data, plateSetting: data_plateSetting, wells: cloneWells, targets: cloneTarget}));
    globeWell = deepClone(wells, globeWell);
  }, [target, sample, group, standard]);

  useEffect(() => {
    //  更新基因表达界面的target和sample
    let experimentSetting_ = {
      targets: [],
      samples: [],
      groups: []
    };
    //如果在plate页面更新target/sample以plate为准
    cloneExperimentSetting = deepClone(experimentSetting, cloneExperimentSetting);
    target.forEach(item => {
      let targetItem = cloneExperimentSetting.targets.find(it=>item.name===it.name);
      if(targetItem){
        experimentSetting_.targets.push({
          name: item.name,
          control: targetItem.control,
          color: item.color,
          e: item.e > 0 ? item.e : 1,
          showChart: true
        });
      }else {
        experimentSetting_.targets.push({
          name: item.name,
          control: false,
          color: item.color,
          e: item.e > 0 ? item.e : 1,
          showChart: true
        });
      }
    });

    sample.forEach(item => {
      let sampleItem = cloneExperimentSetting.samples.find(it=>item.name===it.name);
      if(sampleItem){
        experimentSetting_.samples.push({
          name: item.name,
          reference: sampleItem.reference,
          color: item.color,
          showChart: true,
          type: item.type
        });
      }else {
        experimentSetting_.samples.push({
          name: item.name,
          reference: false,
          color: item.color,
          showChart: true,
          type: item.type
        });
      }
    });

    group.forEach(item => {
      experimentSetting_.groups.push({
        name: item.name,
        reference: false,
        color: item.color,
        showChart: true
      });
    });
    dispatch(saveExperimentSetting(experimentSetting_));
  }, [target, sample, group, standard]);

  //修复基因表达control不更新问题，早在protocol时尚未使用data大数据
  useEffect(() => {
    //  更新基因表达界面的target和sample
    let experimentSetting_ = {
      targets: [],
      samples: [],
      groups: [],
    };
    cloneExperimentSetting = deepClone(experimentSetting, cloneExperimentSetting);
    console.log('experimentSetting',experimentSetting);
    cloneExperimentSetting.targets.forEach(item => {
      experimentSetting_.targets.push({
        name: item.name,
        control: item.control,
        color: item.color,
        e: item.e > 0 ? item.e : 1,
        showChart: true
      });
    });
    cloneExperimentSetting.samples.forEach(item => {
      experimentSetting_.samples.push({
        name: item.name,
        reference: item.reference,
        color: item.color,
        showChart: true,
        type: item.type
      });
    });

    cloneExperimentSetting.groups?.forEach(item => {
      experimentSetting_.groups.push({
        name: item.name,
        reference: item.reference,
        color: item.color,
        showChart: true,
        // type: item.type
      });
    });
    // experimentSetting_.groups = arr;
    console.log(experimentSetting);
    dispatch(saveExperimentSetting(experimentSetting_));
  }, []);

  useEffect(() => {
    data.wells.forEach(item => item.selected && setWellsId(item.sampleUuid));
    setWells(data.wells);
    setTarget(data.plateSetting.targets);
    setSample(data.plateSetting.samples);
    setStandard(data.plateSetting.standard);
    changeWellsCounter(data.wells);
  }, [data]);

  useEffect(() => {
    document.onclick = function () {
      setShowRightMenu(false);
    };
    let [keyCtrl, keyV, keyA] = [false, false, false];
    document.addEventListener("keydown", e => {
      e.ctrlKey && (keyCtrl = true);
      e.key === "v" && (keyV = true);
      e.key === "a" && (keyA = true);
      if (keyCtrl && keyA) {
        copyAllSetting();
      }
      if (keyCtrl && keyV) {
        paste();
      }
    });
    document.addEventListener("keyup", e => {
      e.ctrlKey && (keyCtrl = false);
      e.key === "v" && (keyV = false);
      e.key === "a" && (keyA = false);
    });
  }, []);

  useEffect(() => {
    let count = 0, showName = [];
    endogenousControlTarget.forEach((item, index) => {
      if (item.opt) {
        count++;
        showName.push(item.name);
      }
    });
    switch (count) {
      case 0:
        setEndogenousControl("");
        break;
      case 1:
        setEndogenousControl(showName[0]);
        break;
      default:
        setEndogenousControl("Multiple Controls");
    }
  }, []);

  useEffect(() => {
    let diffEndogenousControlTarget = [];
    let optFlag = [];
    endogenousControlTarget.forEach(item => item.opt && optFlag.push(item.name));
    target.forEach(item => item.name && diffEndogenousControlTarget.push({
      opt: optFlag.includes(item.name),
      name: item.name,
      uuid: item.uuid
    }));
    dispatch(saveEndogenousControlTarget(diffEndogenousControlTarget));
  }, [target]);

  //  获取target library本地存储
  function getTargetLibraryLocalStorage() {
    let result = [];
    let targetLibraryLocalStorage = new Map(JSON.parse(localStorage.getItem("targetLibraryLocalStorage")));
    targetLibraryLocalStorage.forEach(item => {
      result.push({
        value: item.name,
        name: item.name,
        color: item.color,
        channel: item.channel,
        quencher: item.quencher
      });
    });
    return result;
  }

  //  TODO: 框选功能,考虑后期是否使用原生实现
  //  鼠标左键按下监听器
  function mouseDownListener(e) {
    if (e.buttons !== 1) {      //  判断鼠标左键按下
      return;
    }
    e.preventDefault();
    if (e.ctrlKey) {  //  按下ctrl
      wells.forEach((well, index) => well.selected && cloneSelectedWells.push(index));
      setSelectedWells([...new Set(cloneSelectedWells)]); //  记录先前选中的wells
    } else if (e.shiftKey) {  //  按下shift
      wells.forEach((well, index) => well.selected && cloneSelectedWells.push(index));
      setSelectedWells([...new Set(cloneSelectedWells)]); //  记录先前选中的wells
      setLeftMouseDown(true);
      setStartX(e.clientX - wellsContainer.current.offsetLeft); //  设置原点坐标为容器左上角
      setStartY(e.clientY - wellsContainer.current.offsetTop);
    } else {  //  不按ctrl和shift
      setSelectedWells([]);
      setLeftMouseDown(true);
      setStartX(e.clientX - wellsContainer.current.offsetLeft); //  设置原点坐标为容器左上角
      setStartY(e.clientY - wellsContainer.current.offsetTop);
    }
  }

  //  鼠标移动监听器
  function mouseMoveListener(e) {
    let {left, top} = wellsContainer.current.getBoundingClientRect(); //  容器上边(左边)到视窗上边(左边)的距离
    let [nowX, nowY] = [e.clientX - left, e.clientY - top]; //  鼠标当前的位置
    setTimeout(() => {
      setShowWellInfo(false);
      setMouseX(nowX);
      setMouseY(nowY);
    });
    if (!leftMouseDown) {
      return;
    }
    e.preventDefault();
    setSelectBoxLeft(Math.min(nowX, startX));
    setSelectBoxTop(Math.min(nowY, startY));
    setSelectBoxWidth(Math.abs(nowX - startX));
    setSelectBoxHeight(Math.abs(nowY - startY));
    setShowSelectBox(true);
    if (selectBoxWidth > 10 && selectBoxHeight > 10) {
      cloneWells = deepClone(wells, cloneWells);
      cloneWells.forEach(well => well.selected = (WELL_WIDTH + well.col * WELL_LEFT) > selectBoxLeft
        && (WELL_WIDTH + well.row * WELL_LEFT) > selectBoxTop
        && well.col * WELL_LEFT < selectBoxLeft + selectBoxWidth
        && well.row * WELL_LEFT < selectBoxTop + selectBoxHeight);
      (e.ctrlKey || e.shiftKey) && selectedWells.forEach(well => cloneWells[well].selected = true);  //  将先前选中的wells重新设置为true
      setWells(cloneWells);
    }
  }

  //  鼠标左键抬起监听器
  function mouseUpListener() {
    if (!leftMouseDown) {
      return;
    }
    setShowSelectBox(false);
    setLeftMouseDown(false);
    selectTargetAuto(wells);
    selectSampleOrGroupAuto(wells, deepClone(sample, cloneSample), setSample, "sampleName");
    selectSampleOrGroupAuto(wells, deepClone(group, cloneGroup), setGroup, "groupName");
  }

  //  鼠标移出wells面板监听器
  function mouseLeaveListener() {
    if (!leftMouseDown) {
      return;
    }
    setShowSelectBox(false);
    setLeftMouseDown(false);
    selectTargetAuto(wells);
    selectSampleOrGroupAuto(wells, deepClone(sample, cloneSample), setSample, "sampleName");
    selectSampleOrGroupAuto(wells, deepClone(group, cloneGroup), setGroup, "groupName");
  }

  //  选择一个well
  function selectSingleWell(e, item) {
    let position = item.row * 12 + item.col;
    cloneWells = deepClone(wells, cloneWells);
    (e.ctrlKey || e.shiftKey) || cloneWells.forEach((well, index) => position === index || (well.selected = false));
    cloneWells[position].selected = !cloneWells[position].selected;
    setWells(cloneWells);
    selectTargetAuto(cloneWells);
    selectSampleOrGroupAuto(cloneWells, deepClone(sample, cloneSample), setSample, "sampleName");
    selectSampleOrGroupAuto(cloneWells, deepClone(group, cloneGroup), setGroup, "groupName");
  }

  //  选择整行列的wells
  function selectRowOrCol(e, indey, type) {
    cloneWells = deepClone(wells, cloneWells);
    let selectedWells = cloneWells.filter(well => well[type] === indey && well.selected),
      count = selectedWells.length;
    if ((type === "row" && count === 12) || (type === "col" && count === 8)) {  //  如果全选则取消全选
      selectedWells.forEach(wells => wells.selected = false);
      setWells(cloneWells);
      return;
    }
    cloneWells.forEach(well => {
      (e.ctrlKey || e.shiftKey) || (well.selected = false);
      well[type] === indey && (well.selected = true);
    });
    setWells(cloneWells);
    selectTargetAuto(cloneWells);
    selectSampleOrGroupAuto(cloneWells, deepClone(sample, cloneSample), setSample, "sampleName");
    selectSampleOrGroupAuto(cloneWells, deepClone(group, cloneGroup), setGroup, "groupName");
  }

  //  选择全部的wells
  function selectAllWells() {
    cloneWells = deepClone(wells, cloneWells);
    if (wells.some(item => !item.selected)) {
      cloneWells.forEach(well => well.selected = true);
    } else {
      cloneWells.forEach(well => well.selected = false);
    }
    setWells(cloneWells);
    selectTargetAuto(cloneWells);
    selectSampleOrGroupAuto(cloneWells, deepClone(sample, cloneSample), setSample, "sampleName");
    selectSampleOrGroupAuto(cloneWells, deepClone(group, cloneGroup), setGroup, "groupName");
  }

  //  选择well后在target处自动变更Opt
  function selectTargetAuto(_wells) {
    cloneTarget = deepClone(target, cloneTarget);
    cloneTarget.forEach(item => item.opt = false);
    let selectedWells = _wells.filter(well => well.selected),
      wellSelectedCount = selectedWells.length,
      targetsName = new Map();
    _wells.forEach(well => well.selected && well.targets.forEach(target =>
      targetsName.has(target.name)
        ? targetsName.set(target.name, targetsName.get(target.name) + 1)
        : targetsName.set(target.name, 1)));
    targetsName.forEach((targetNameCount, targetName) => targetNameCount <= wellSelectedCount && cloneTarget.forEach(item => item.name === targetName && (item.opt = true)));
    setTarget(cloneTarget);
  }

  //  选择well后在sample或group处自动变更Opt
  function selectSampleOrGroupAuto(_wells, cloneItem, setAction, type) {
    cloneItem.forEach(item => item.opt = false);
    let selectedWells = _wells.filter(well => well.selected),
      wellSelectedCount = selectedWells.length,
      nameMap = new Map();
    _wells.forEach(well => {
      if (well.selected && well[type] !== "") {
        nameMap.has(well[type])
          ? nameMap.set(well[type], nameMap.get(well[type]) + 1)
          : nameMap.set(well[type], 1);
      }
    });
    nameMap.forEach((groupNameCount, groupName) => groupNameCount <= wellSelectedCount && cloneItem.forEach(item => item.name === groupName && (item.opt = true)));
    setAction(cloneItem);
  }

  //  右键功能
  function rightButtonClick(e) {
    e.preventDefault();
    let {left, top} = wellsContainer.current.getBoundingClientRect(); //  容器上边(左边)到视窗上边(左边)的距离
    let [nowX, nowY] = [e.clientX - left, e.clientY - top]; //  鼠标当前的位置
    setRightMenuLeft(nowX);
    setRightMenuTop(nowY);
    setShowRightMenu(true);
  }

  //  复制wells的属性
  function copyAllSetting() {
    globeWell.some(well => well.selected && (globeCopyWell = well));
  }

  //  粘贴wells的属性
  function paste() {
    if (Object.keys(globeCopyWell).length === 0) {
      return;
    }
    cloneWells = deepClone(globeWell, cloneWells);
    cloneWells.forEach((well, index) => well.selected && (cloneWells[index] = {...globeCopyWell, col: well.col, row: well.row}));
    setWells(cloneWells);
    changeWellsCounter(cloneWells);
  }

  //  改变 Wells Counter
  function changeWellsCounter(_wells) {
    cloneWellsCounter = deepClone(wellsCounter, cloneWellsCounter);
    cloneWellsCounter.forEach((item, index) => item.count = index === 6 ? 96 : 0);
    _wells.forEach(item => {
      switch (item.type) {
        case WELL_TYPE.UNK:
          cloneWellsCounter[0].count++;
          cloneWellsCounter[6].count--;
          break;
        case WELL_TYPE.NTC:
          cloneWellsCounter[1].count++;
          cloneWellsCounter[6].count--;
          break;
        case WELL_TYPE.POS:
          cloneWellsCounter[2].count++;
          cloneWellsCounter[6].count--;
          break;
        case WELL_TYPE.NEG:
          cloneWellsCounter[3].count++;
          cloneWellsCounter[6].count--;
          break;
        case WELL_TYPE.NRT:
          cloneWellsCounter[4].count++;
          cloneWellsCounter[6].count--;
          break;
        case WELL_TYPE.STD:
          cloneWellsCounter[5].count++;
          cloneWellsCounter[6].count--;
          break;
      }
    });
    //  设置export对象
    let cloneExportObj = {}, task = "";
    cloneExportObj = deepClone(isCN ? exportObjCn : exportObj, cloneExportObj);
    cloneWellsCounter.forEach(item => task = task + `${item.name}: ${item.count}个\n`);
    cloneExportObj.plate.task = task;
    isCN ? dispatch(saveExportObjCn(cloneExportObj))
      : dispatch(saveExportObj(cloneExportObj));
    setWellsCounter(cloneWellsCounter);
  }

  //  清除plate,会清除孔板数据,无法进行画图
  function clear() {
    globeCopyWell = {};
    cloneWells = deepClone(wells, cloneWells);
    cloneWellsCounter = deepClone(wellsCounter, cloneWellsCounter);
    cloneWellsCounter.forEach((item, index) => item.count = index === 6 ? 96 : 0);
    setWellsCounter(cloneWellsCounter);
    cloneWells.forEach(well => {
      well.groupColor = "";
      well.groupName = "";
      well.sampleName = "";
      well.sampleUuid = "";
      well.groupUuid = "";
      well.groupColor = "";
      well.targets = [];
      well.type = "";
    });
    setWells(cloneWells);
    setTarget([]);
    setSample([]);
    setStandard({
      name: "STD-1",
      initialQuantity: 100000000,
      showInitialQuantity: "1.000E+8",
      replicateArrange: "down",
      selectTarget: [],
      standardNumber: 5,
      startingAmount: 1,
      factor: 10,
      dilutionFactor: 10,
      unit: "copies/μL",
      replicates: 3,
      increasing: false,
      assignment: 1
    });
    dispatch(saveTargetName([]));
    setTargetNameArr([]);
  }

  //清除plate里的targets
  function clearTargets() {
    cloneWells = deepClone(wells, cloneWells);
    cloneWells.forEach(well => {
      well.targets = [];
    });
    setWells(cloneWells);
    setTarget([]);
    dispatch(saveTargetName([]));
    setTargetNameArr([]);
  }

  //清除plate里的samples
  function clearSamples() {
    cloneWells = deepClone(wells, cloneWells);
    cloneWellsCounter = deepClone(wellsCounter, cloneWellsCounter);
    cloneWellsCounter.forEach((item, index) => item.count = index === 6 ? 96 : 0);
    setWellsCounter(cloneWellsCounter);
    cloneWells.forEach(well => {
      well.sampleName = "";
      well.sampleUuid = "";
      well.sampleColor = "";
      well.sampleControl = false;
      well.type = "";
    });
    setWells(cloneWells);
    setSample([]);
  }

  //  清除选中plate
  function clearSelected() {
    cloneWellsCounter = deepClone(wellsCounter, cloneWellsCounter);
    cloneWells = deepClone(wells, cloneWells);
    cloneWells.forEach(well => {
      if (well.selected) {
        well.groupColor = "";
        well.groupName = "";
        well.sampleName = "";
        well.sampleUuid = "";
        well.groupUuid = "";
        well.groupColor = "";
        well.targets = [];
        well.type = "";
      }
    });
    changeWellsCounter(cloneWells);
    setWells(cloneWells);
    dispatch(saveData({...data, wells: cloneWells}));
  }

  //  选择内参基因
  function selectSingleEndogenousControl(value) {
    cloneEndogenousControlTarget = deepClone(endogenousControlTarget, cloneEndogenousControlTarget);
    cloneEndogenousControlTarget.forEach(item => {
      item.opt = item.name === value;
    });
    dispatch(saveEndogenousControlTarget(cloneEndogenousControlTarget));
    // 与geneExpression界面的experimentSetting联动
    cloneExperimentSetting = deepClone(experimentSetting, cloneExperimentSetting);
    cloneExperimentSetting.targets.forEach(item => {
      item.control = item.name === value;
    });
    dispatch(saveExperimentSetting(cloneExperimentSetting));
    setEndogenousControl(value);
  }

  //  选择多内参基因
  function selectEndogenousControl(indey) {
    let showEndogenousControl = [];
    cloneEndogenousControlTarget = deepClone(endogenousControlTarget, cloneEndogenousControlTarget);
    cloneEndogenousControlTarget[indey].opt = !cloneEndogenousControlTarget[indey].opt;
    cloneEndogenousControlTarget.forEach(item => item.opt && showEndogenousControl.push(item.name));
    dispatch(saveEndogenousControlTarget(cloneEndogenousControlTarget));
    switch (showEndogenousControl.length) {
      case 0:
        setEndogenousControl("");
        break;
      case 1:
        setEndogenousControl(showEndogenousControl[0]);
        break;
      default:
        setEndogenousControl("Multiple Controls");
    }
    // 与geneExpression界面的experimentSetting联动
    cloneExperimentSetting = deepClone(experimentSetting, cloneExperimentSetting);
    cloneExperimentSetting.targets[indey].control = !cloneExperimentSetting.targets[indey].control;
    dispatch(saveExperimentSetting(cloneExperimentSetting));
  }

  //  选择Reference Sample
  function selectReferenceSample(value) {
    dispatch(saveReferenceSample(value));
    // 与geneExpression界面的experimentSetting联动
    cloneExperimentSetting = deepClone(experimentSetting, cloneExperimentSetting);
    cloneExperimentSetting.samples.forEach(item => item.reference = item.name === value);
    dispatch(saveExperimentSetting(cloneExperimentSetting));
  }

  //  鼠标悬停显示信息
  const mouseOverAction = useDebounce((value) => {
    if (!mouseIn) {
      return;
    }
    let target = "",
      quencher = "",
      quantity = "";
    value.targets.forEach(item => {
      target += `${item.name} `;
      quencher += `${item.quencher} `;
      quantity += `${Number(value.lines[item.channelIndex].sq).toExponential(2)} `;
    });
    setWellInfo({
      target,
      sample: value.sampleName,
      task: value.type,
      quencher,
      quantity
    });
    setShowWellInfo(true);
    setWellInfoLeft(mouseX);
    setWellInfoTop(mouseY);
  }, 1000);

  return (
    <div>
      <Header name={isCN ? "孔板设置" : "Plate"}
              imgPosition="-100px"
              isLoad={true}
              isSave={true}
              loadType={LOAD_PLATE}
      />
      <section className="mainSection" style={{display: "flex", height: "90vh"}}>
        <div className="platePagePart0">
          <div className="platePageTable">
            <section className="platePageTableTop" onMouseLeave={mouseLeaveListener}>
              <div>
                <div onClick={selectAllWells}/>
                <div>
                  {
                    WELLS_COLUMN.map((col, index) => <div key={col} onClick={e => selectRowOrCol(e, index, "col")}>{col}</div>)
                  }
                </div>
              </div>
              <div>
                {
                  WELLS_ROW.map((row, index) => <div key={row} onClick={e => selectRowOrCol(e, index, "row")}>{row}</div>)
                }
              </div>
              <div ref={wellsContainer}
                   onMouseDown={e => mouseDownListener(e)}
                   onMouseMove={e => mouseMoveListener(e)}
                   onMouseUp={mouseUpListener}
                   onContextMenu={e => rightButtonClick(e)}
                   onMouseOver={() => setMouseIn(true)}
                   onMouseOut={() => setMouseIn(false)}
              >
                {
                  wells.map(well => (
                    <div key={well.row * 12 + well.col}
                         onClick={e => selectSingleWell(e, well)}
                         onMouseOver={() => mouseOverAction(well)}
                         onMouseLeave={() => setShowWellInfo(false)}
                         style={well.selected
                           ? {borderColor: "#fff", backgroundColor: `${well.groupColor}`}
                           : {borderColor: `${SAMPLE_TASK[well.type]}`, backgroundColor: `${well.groupColor}`}}
                    >
                      <div style={well.sampleName ? {backgroundColor: `${well.sampleColor}`} : null}>{well.sampleName}</div>
                      <ul>
                        {
                          well.targets.map(target => (
                            <li key={target.name} style={{backgroundColor: target.color}}/>
                          ))
                        }
                      </ul>
                    </div>
                  ))
                }
                {
                  showSelectBox
                    ? <div className="platePageSelectBox" style={{left: `${selectBoxLeft}px`, top: `${selectBoxTop}px`, width: `${selectBoxWidth}px`, height: `${selectBoxHeight}px`}}/>
                    : null
                }
                {
                  showRightMenu
                    ? <aside
                      className="platePageRightMenu"
                      style={{left: `${rightMenuLeft}px`, top: `${rightMenuTop}px`}}
                    >
                      <div className="active"
                           onClick={copyAllSetting}
                      >Copy <u>A</u>ll Setting (A)<span>Ctrl+A</span></div>
                      <div className="active"
                           onClick={paste}
                      ><u>P</u>aste (P)<span>Ctrl+V</span></div>
                      <hr/>
                      <div className="active" onClick={clear}>Clear All Setting</div>
                      <div className="active" onClick={clearTargets}>Clear Targets</div>
                      <div className="active" onClick={clearSamples}>Clear Samples</div>
                    </aside>
                    : null
                }
                {
                  showWellInfo
                    ? <aside className="wellInfoAside"
                             style={{left: `${wellInfoLeft}px`, top: `${wellInfoTop}px`}}
                    >
                      <div>
                        <div>Target:</div>
                        <div>{wellInfo.target}</div>
                      </div>
                      <div>
                        <div>Sample:</div>
                        <div>{wellInfo.sample}</div>
                      </div>
                      <div>
                        <div>Task:</div>
                        <div>{wellInfo.task}</div>
                      </div>
                      <div>
                        <div>Quantity:</div>
                        <div>{wellInfo.quantity}</div>
                      </div>
                    </aside>
                    : null
                }
              </div>
            </section>
            <section className="platePageTableBottom">
              <div>{isCN ? "孔位计数" : "Wells Counter"}</div>
              <ul>
                {
                  wellsCounter.map(item => (
                    <li key={item.name}>
                      <div style={{backgroundColor: `${item.color}`}}>{item.name}</div>
                      <div>{item.count}</div>
                    </li>
                  ))
                }
              </ul>
            </section>
          </div>
          <div>
            <div className="platePageRelative">
              <Title name={isCN ? "相对定量设置" : "Relative Quantitation Setting"}/>
              <div>
                <div>{isCN ? "对照样品" : "Reference Sample"}</div>
                <Dropdown
                  overlay={
                    <Menu>
                      {
                        sample.map(item => (
                          <Menu.Item key={item.name}>
                            <div style={{...MENU_STYLE, width: "180px"}}
                                 onClick={() => selectReferenceSample(item.name)}
                            >{item.name}</div>
                          </Menu.Item>
                        ))
                      }
                    </Menu>
                  }
                  overlayClassName="antdDropDownStyle"
                  placement="bottomCenter"
                  trigger={['click']}
                >
                  <div>{referenceSample}</div>
                </Dropdown>
              </div>
              <div>
                <div>{isCN ? "内参基因" : "Endogenous Control"}</div>
                <Dropdown
                  overlay={
                    <Menu>
                      <Menu.Item>
                        <div style={{...MENU_STYLE, width: "180px"}}
                             onClick={() => setEndogenousControlBox(true)}
                        >Multiple
                        </div>
                      </Menu.Item>
                      {
                        endogenousControlTarget.map(item => (
                          <Menu.Item key={item.uuid}>
                            <div style={{...MENU_STYLE, width: "180px"}}
                                 onClick={() => selectSingleEndogenousControl(item.name)}
                            >{item.name}</div>
                          </Menu.Item>
                        ))
                      }
                    </Menu>
                  }
                  overlayClassName="antdDropDownStyle"
                  placement="bottomCenter"
                  trigger={['click']}
                >
                  <div>{endogenousControl}</div>
                </Dropdown>
              </div>
            </div>
            <PlateGroup wells={wells}
                        setWells={setWells}
                        group={group}
                        setGroup={setGroup}
            />
          </div>
        </div>
        <div className="platePagePart1">
          <header>
            <div>
              <p/>
              <p onClick={clearSelected}>{isCN ? "清除" : "Clear"}</p>
            </div>
            <div>{isCN ? "分 配" : "Assignments"}</div>
            <ExperimentName/>
          </header>
          <PlateTargets wells={wells}
                        setWells={setWells}
                        target={target}
                        setTarget={setTarget}
                        targetLibraryStorage={targetLibraryStorage}
                        setShowTargetsLibrary={setShowTargetsLibrary}
                        setTargetLibrary={setTargetLibrary}
                        channels={channels}
                        targetNameArr={targetNameArr}
                        setTargetNameArr={setTargetNameArr}
          />
          <PlateSamples wells={wells}
                        setWells={setWells}
                        wellsId={wellsId}
                        setWellsId={setWellsId}
                        sample={sample}
                        setSample={setSample}
                        wellsCounter={wellsCounter}
                        setWellsCounter={setWellsCounter}
                        changeWellsCounter={changeWellsCounter}
                        setShowSampleLibrary={setShowSampleLibrary}
          />
          <PlateStandard wells={wells}
                         setWells={setWells}
                         sample={sample}
                         setSample={setSample}
                         target={target}
                         setTarget={setTarget}
                         wellsCounter={wellsCounter}
                         setWellsCounter={setWellsCounter}
                         standard={standard}
                         setStandard={setStandard}
          />
        </div>
      </section>
      {
        showTargetsLibrary
          ? <PlateTargetLibrary targetLibrary={targetLibrary}
                                setTargetLibrary={setTargetLibrary}
                                setTargetLibraryStorage={setTargetLibraryStorage}
                                setShowTargetsLibrary={setShowTargetsLibrary}
                                getTargetLibraryLocalStorage={getTargetLibraryLocalStorage}
                                channels={channels}
          />
          : null
      }

      {
        showSampleLibrary
          ? <PlateSampleLibrary setShowSampleLibrary={setShowSampleLibrary}
                                sample={sample}
                                setSample={setSample}
                                samples={samples}
                                setSamples={setSamples}
                                target={target}
                                setTarget={setTarget}
                                group={group}
                                setGroup={setGroup}
                                wells={wells}
                                setWells={setWells}
                                wellsCounter={wellsCounter}
                                setWellsCounter={setWellsCounter}
                                changeWellsCounter={changeWellsCounter}
          />
          : null
      }

      {
        endogenousControlBox ?
          <aside className="plateEndogenousControlBox">
            <header>
              <div>
                <p>Select Multiple Endogenous Controls</p>
                <p onClick={() => setEndogenousControlBox(false)}/>
              </div>
              <hr/>
            </header>
            <ul className="scrollBarStyle">
              {endogenousControlTarget.map((item, index) => (
                <li key={index}>
                  <div className={item.opt ? "selectedStyle" : ""} onClick={() => selectEndogenousControl(index)}/>
                  <div>{item.name}</div>
                </li>
              ))}
            </ul>
          </aside>
          : null
      }
    </div>
  );
});
